using System;
using System.Collections.Generic;
using UnityEngine;

namespace NodeCanvas
{
	public abstract class GraphOwner : MonoBehaviour
	{
		public enum EnableAction
		{
			StartBehaviour = 0,
			DoNothing = 1
		}

		public enum DisableAction
		{
			StopBehaviour = 0,
			PauseBehaviour = 1,
			DoNothing = 2
		}

		public EnableAction onEnable;

		public DisableAction onDisable;

		[SerializeField]
		private Blackboard _blackboard;

		private Dictionary<Graph, Graph> instances = new Dictionary<Graph, Graph>();

		private static bool isQuiting;

		public bool isRunning
		{
			get
			{
				return behaviour != null && behaviour.isRunning;
			}
		}

		public bool isPaused
		{
			get
			{
				return behaviour != null && behaviour.isPaused;
			}
		}

		public float elapsedTime
		{
			get
			{
				return (!(behaviour != null)) ? 0f : behaviour.elapsedTime;
			}
		}

		public Blackboard blackboard
		{
			get
			{
				return _blackboard;
			}
			set
			{
				_blackboard = value;
				if (behaviour != null)
				{
					behaviour.blackboard = value;
				}
			}
		}

		public abstract Graph behaviour { get; set; }

		public abstract Type graphType { get; }

		public void StartBehaviour()
		{
			behaviour = GetInstance(behaviour);
			if (behaviour != null)
			{
				behaviour.StartGraph(this, blackboard);
			}
		}

		public void StartBehaviour(Action callback)
		{
			behaviour = GetInstance(behaviour);
			if (behaviour != null)
			{
				behaviour.StartGraph(this, blackboard, callback);
			}
		}

		public void StartBehaviour(Graph newGraph)
		{
			SwitchBehaviour(newGraph);
		}

		public void StartBehaviour(Graph newGraph, Action callback)
		{
			SwitchBehaviour(newGraph, callback);
		}

		public void StopBehaviour()
		{
			if (behaviour != null)
			{
				behaviour.StopGraph();
			}
		}

		public void PauseBehaviour()
		{
			if (behaviour != null)
			{
				behaviour.PauseGraph();
			}
		}

		public void SwitchBehaviour(Graph newGraph)
		{
			SwitchBehaviour(newGraph, null);
		}

		public void SwitchBehaviour(Graph newGraph, Action callback)
		{
			if (newGraph.GetType() != graphType)
			{
				Debug.LogWarning("Incompatible graph types." + GetType().Name + " can be assigned graphs of type " + graphType.Name);
				return;
			}
			StopBehaviour();
			behaviour = newGraph;
			StartBehaviour(callback);
		}

		public void SendEvent(string eventName)
		{
			if (behaviour != null)
			{
				behaviour.SendEvent(eventName);
			}
		}

		public void SendGlobalEvent(string eventName)
		{
			Graph.SendGlobalEvent(eventName);
		}

		public new void SendMessage(string name)
		{
			SendMessage(name, null);
		}

		public new void SendMessage(string name, object arg)
		{
			if (behaviour != null)
			{
				behaviour.SendMessage(name, arg);
			}
		}

		public void SendTaskMessage(string name)
		{
			SendTaskMessage(name, null);
		}

		public void SendTaskMessage(string name, object arg)
		{
			if (behaviour != null)
			{
				behaviour.SendTaskMessage(name, arg);
			}
		}

		private Graph GetInstance(Graph originalGraph)
		{
			if (!Application.isPlaying)
			{
				return originalGraph;
			}
			if (originalGraph == null)
			{
				return null;
			}
			Graph graph;
			if (originalGraph.transform.parent == base.transform)
			{
				graph = originalGraph;
			}
			else if (instances.ContainsKey(originalGraph))
			{
				graph = instances[behaviour];
			}
			else
			{
				graph = UnityEngine.Object.Instantiate(originalGraph, base.transform.position, base.transform.rotation);
				graph.transform.parent = base.transform;
				instances[originalGraph] = graph;
			}
			graph.agent = this;
			graph.blackboard = blackboard;
			graph.gameObject.hideFlags = (Graph.doHide ? HideFlags.HideAndDontSave : HideFlags.None);
			return graph;
		}

		protected void OnEnable()
		{
			behaviour = GetInstance(behaviour);
			if (onEnable == EnableAction.StartBehaviour)
			{
				StartBehaviour();
			}
		}

		protected void OnDisable()
		{
			if (!isQuiting)
			{
				if (onDisable == DisableAction.StopBehaviour)
				{
					StopBehaviour();
				}
				if (onDisable == DisableAction.PauseBehaviour)
				{
					PauseBehaviour();
				}
			}
		}

		protected void OnApplicationQuit()
		{
			isQuiting = true;
		}

		protected void Reset()
		{
			blackboard = base.gameObject.GetComponent<Blackboard>();
			if (blackboard == null)
			{
				blackboard = base.gameObject.AddComponent<Blackboard>();
			}
		}

		protected void OnDrawGizmos()
		{
			Gizmos.DrawIcon(base.transform.position, "GraphOwnerGizmo.png", true);
		}
	}
}
